import time
import re

import argparse


def get_user_response(message: str) -> str:
    """ Получаем ответ от пользователя """

    while True:
        try:
            response: str = input(message)
            return response
        except UnicodeDecodeError:
            continue


class FancyTimer():

    def __init__(self):

        self.information_about_pauses = []
        self.launch_time = time.time()
        self.starting_the_timer = time.ctime()
        self.time_to_pause = 0
        self.pause_time = 0

        self.data = self.get_input_parameters()
        self.convert_the_time_to_the_desired_view()
        self.finish_in = self.launch_time + self.duration_seconds

        self.get_started()


    def get_input_parameters(self):

        """ Получаем сходные аргументы """

        parser = argparse.ArgumentParser()
        parser.add_argument('-t', dest='ti', default='4')
        arguments = parser.parse_args()

        ti = arguments.ti
        data = (ti,)

        return data


    def convert_minutes_to_hours(self, minutes):

        """ Преобразовываем минуты в часы """

        hours, minutes = str(minutes / 60).split('.')
        minutes = int(float(f'0.{minutes}') * 60)

        t = f'{hours}h {minutes}m'

        return t


    def get_history_of_pauses_list(self, little):

        def get_the_time_spent_on_pauses(list_of_pauses_message):

            """ Получаем время затарченное на паузы """

            list_of_pauses = []

            with open('list_of_pauses.txt') as file:

                for line in file:

                    pause = line.strip()
                    pause = float('.'.join(re.findall(r'\d+', pause.split('or')[-1])))
                    list_of_pauses.append(pause)

            total = sum(list_of_pauses) / 60
            hours = self.convert_minutes_to_hours(total)
            message = f'[>] Time spent on pauses - {hours}\n'
            list_of_pauses_message += message

            return list_of_pauses_message


        def indicate_that_there_is_no_pause(temp_list_of_pauses):

            """ Указвыем то, что нет пауз, если так """

            list_of_pauses = ''

            if not temp_list_of_pauses:

                message = f'[>] There hasn\'t been a single pause yet.\n'
                list_of_pauses += message

            return list_of_pauses


        def add_pauses_to_output(temp_list_of_pauses, list_of_pauses):

            """ Добавляем паузы в список """

            for pause in temp_list_of_pauses:

                pause = f'[>] {pause}\n'
                list_of_pauses += pause

            return list_of_pauses


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        """ Получаем список пауз """

        temp_list_of_pauses = []

        with open('list_of_pauses.txt') as file:

            for line in file:

                pause = line.strip()
                temp_list_of_pauses.append(pause)

        temp_list_of_pauses = temp_list_of_pauses[-2:] if little == 'yes' else temp_list_of_pauses

        list_of_pauses = indicate_that_there_is_no_pause(temp_list_of_pauses)
        list_of_pauses = add_pauses_to_output(temp_list_of_pauses, list_of_pauses)

        time_spent_on_pauses = get_the_time_spent_on_pauses(list_of_pauses)

        return time_spent_on_pauses


    def get_a_message_to_display(self):

        """ Получаем сообщение для показа """

        def get_the_end_time():

            """ Получаем время окончания """

            end_time = time.ctime(self.finish_in)

            return end_time



        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        end_time = get_the_end_time()
        message = '###############\n\n'

        t = 't - get information about the time'
        pause = 'p - put it on pause'
        history_of_pauses = 'h - view the history of pauses'
        list_of_pauses = 'c - clear the list of pauses\n'

        starting_the_timer = f'The time was set in .... {self.starting_the_timer}'
        end_time = f'The end will be in ..... {end_time}\n'

        history_of_pauses_list = self.get_history_of_pauses_list(little='yes')

        elements = (t, pause, history_of_pauses, list_of_pauses, starting_the_timer, end_time, history_of_pauses_list)

        for element in elements:

            if '[>]' in element:

                message += element
                continue

            done_element = '[*] ' + element + '\n'

            if not re.findall(r'^\w{1} -', element):

                done_element = '[$] ' + element + '\n'
                message += done_element
                continue

            message += done_element


        return message


    def show_information(self, time_has_passed_seconds):

        """ Показываем информацию """

        def get_the_past_tense():

            """ Получаем прошедшее время """

            seconds = self.finish_in - time.time()
            past_tense_minutes = (self.duration_seconds - seconds) / 60
            hours = self.convert_minutes_to_hours(past_tense_minutes)

            return hours


        def get_remaining_time():

            """ Получаем оставшееся время """

            minutes = (self.finish_in - time.time()) / 60
            hours = self.convert_minutes_to_hours(minutes)

            return hours


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        remaining_time = get_remaining_time()
        past_tense = get_the_past_tense()

        print(f'[%] Passed ~ {past_tense}; Left - {remaining_time}')
        print()


    def get_the_past_tense(self):

        """ Получить прошедшее время """

        if self.time_to_pause:

            self.launch_time += self.pause_time
            time_has_passed = time.time() - self.launch_time

        else:

            time_has_passed = time.time() - self.launch_time

        self.show_information(time_has_passed)

        self.time_to_pause = 0


    def put_a_pause(self):

        """ Ставим паузу """

        def work_with_the_answer(well_what):

            """ Работаем с ответом """

            with open('list_of_pauses.txt', 'a') as file:

                if well_what in ('y', '', ' '):

                    file.write('Without a note.')
                    return 'go_out'

                else:

                    file.write(well_what.strip())
                    return 'go_out'


        def add_a_note(pause_time, pause_time_seconds):

            """ Дописываем время потраченное не заметку в заметку, вот как """

            with open('list_of_pauses.txt', 'a') as file:

                message = f' - {pause_time} or {pause_time_seconds}s\n'
                file.write(message)


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        self.time_to_pause = time.time()
        pause_start_time = time.time()

        while True:

            pause_setting_time_message = f'\n[*] The pause was set ...... {time.ctime(pause_start_time)}'
            how_to_specify_a_note = f'[*] For a note to pause, write: note: Your note'

            print(pause_setting_time_message)
            print(how_to_specify_a_note)

            well_what = get_user_response('[?] To turn the timer, enter "y"\n\n>>> ')
            result = work_with_the_answer(well_what)
            if result == 'go_out': break

        pause_time_seconds = time.time() - pause_start_time
        self.finish_in += pause_time_seconds
        pause_time_minutes = pause_time_seconds / 60
        pause_time = self.convert_minutes_to_hours(pause_time_minutes)

        add_a_note(pause_time, pause_time_seconds)

        print(f'\n[*] The pause took - {pause_time}\n')


    def clear_the_list_of_pauses(self):

        """ Очищаем список пауз """

        while True:

            well_what = get_user_response('\n[?] Clear the list of pauses? [y|n]\n\n')

            if well_what == 'y':

                with open('list_of_pauses.txt', 'w') as file:

                    file.write('')
                    print('\n[*] The list of pauses has been cleared.\n')

                    break

            elif well_what == 'n':

                print('[*] The list of pauses remained the same.\n')

                break

            else:

                print(f'[*] The "{well_what}" command is missing. Please try again.')
                continue


    def show_the_history_of_pauses(self):

        """ Показываем историю пауз """

        message = self.get_history_of_pauses_list(little='no')

        print(f'\n[>] Full list of pause:')
        print(message)


    def record_the_time_and_exit(self):

        """ Записываем время и выходим """

        pass


    def convert_the_time_to_the_desired_view(self):

        """ Переводим время в нужный вид """

        duration = self.data[0]

        if re.findall(r'\.', duration):

            hours, minutes = list(map(int, re.split(r'\.', duration)))
            minutes = hours * 60 + minutes
            seconds = minutes * 60
            self.duration_seconds = seconds

        else:

            seconds = int(duration) * 60 * 60
            self.duration_seconds = seconds


    def get_started(self):

        """ Начинаем """

        while True:

            message_to_display = self.get_a_message_to_display()
            what_to_do = get_user_response(message_to_display)
            what_to_do = what_to_do if what_to_do else 't'

            try:

                a_set_of_actions = {
                    't': self.get_the_past_tense,
                    'p': self.put_a_pause,
                    'c': self.clear_the_list_of_pauses,
                    'h': self.show_the_history_of_pauses,
                    'q': self.record_the_time_and_exit
                }

                result = a_set_of_actions[what_to_do]()

            except KeyError as error:

                print(f'\n[*] The passed argument "{what_to_do}" is missing\n')



# ТОЧКА ВХОДА

if __name__ == '__main__':

    a = FancyTimer()
